<?php

namespace JsonLowCode\UI;

use JsonLowCode\Schema;
use JsonLowCode\Traits\Props\HasBordered;
use JsonLowCode\Traits\Props\HasLoading;
use JsonLowCode\Traits\Props\HasName;
use JsonLowCode\Traits\Props\HasSize;
use JsonLowCode\Traits\Slots\HasSlotEmpty;
use JsonLowCode\Traits\Slots\HasSlotFooter;
use JsonLowCode\Traits\Slots\HasSlotHeader;
use JsonLowCode\Traits\Slots\HasSlotLoading;

/**
 * AppTable组件
 * @method static AppTable make(array $attributes = []) AppTable组件
 */
class AppTable extends Schema
{
    use HasName, HasBordered, HasLoading, HasSize;
    use HasSlotHeader, HasSlotFooter, HasSlotLoading, HasSlotEmpty;

    protected string $componentName = "AppTable";

    protected string $apiUrl = "";

    public function __construct($attributes = [])
    {
        parent::__construct($attributes);
    }

    /**
     * 表格的操作组
     * @param string|array $actions
     * @return $this
     */
    public function actions(string|array $actions): static
    {
        return $this->prop('actions',$actions);
    }

    /**
     * 表格的字段组
     * @param string|array $columns
     * @return $this
     */
    public function columns(string|array $columns): static
    {
        return $this->prop('columns',$columns);
    }

    /**
     * 表格的数据
     * @param array $data
     * @return $this
     */
    public function data(array $data): static
    {
        return $this->prop('data', $data);
    }

    /**
     * 是否开启远程api
     * @param bool $remote
     * @return $this
     */
    public function remote(bool $remote = true): static
    {
        return $this->prop("remote",$remote);
    }

    /**
     * 表格的远程请求url
     * @param string $apiUrl
     * @return $this
     */
    public function apiUrl(string $apiUrl): static
    {
        $this->remote();
        $this->apiUrl = $apiUrl;
        return $this->prop('apiUrl',$apiUrl);
    }


    public function getApiUrl(): string
    {
        return $this->apiUrl;
    }

    /**
     * 是否显示分页
     * @param string|bool $showPage
     * @return $this
     */
    public function showPage(string|bool $showPage = true): static
    {
        return $this->prop("showPage",$showPage);
    }


    /**
     * 是否显示header头部
     * @param string|bool $showHeader
     * @return $this
     */
    public function showHeader(string|bool $showHeader = true): static
    {
        return $this->prop("showHeader",$showHeader);
    }

    /**
     * 是否显示search搜索部分
     * @param string|bool $showSearch
     * @return $this
     */
    public function showSearch(string|bool $showSearch = true): static
    {
        return $this->prop("showSearch",$showSearch);
    }

    /**
     * 是否默认展示搜索框
     * @param string|bool $showHeaderCollapse
     * @return $this
     */
    public function showHeaderCollapse(string|bool $showHeaderCollapse = true): static
    {
        return $this->prop("showHeaderCollapse",$showHeaderCollapse);
    }

    /**
     * 是否默认展示全屏按钮
     * @param string|bool $showFullscreen
     * @return $this
     */
    public function showFullscreen(string|bool $showFullscreen = true): static
    {
        return $this->prop("showFullscreen",$showFullscreen);
    }


    /**
     * 是否显示左侧工具栏
     * @param string|bool $showLeftTool
     * @return $this
     */
    public function showLeftTool(string|bool $showLeftTool = true): static
    {
        return $this->prop("showLeftTool",$showLeftTool);
    }

    /**
     * 是否显示右侧工具栏
     * @param string|bool $showRightTool
     * @return $this
     */
    public function showRightTool(string|bool $showRightTool = true): static
    {
        return $this->prop("showRightTool",$showRightTool);
    }

    /**
     * 是否显示 bottom border
     * @param string|bool $bottomBordered
     * @return $this
     */
    public function bottomBordered(string|bool $bottomBordered = true): static
    {
        return $this->prop("bottomBordered",$bottomBordered);
    }

    /**
     * 是否允许级联勾选还没有完全加载的节点。如果你要用这个属性，请记住 checked-row-keys 可能是不完整的
     * @param string|bool $allowCheckingNotLoaded
     * @return $this
     */
    public function allowCheckingNotLoaded(string|bool $allowCheckingNotLoaded = true): static
    {
        return $this->prop("allowCheckingNotLoaded",$allowCheckingNotLoaded);
    }

    /**
     * 被选中的列的 key
     * @param string|array $checkedRowKeys (string[] | int[])
     * @return $this
     */
    public function checkedRowKeys(string|array $checkedRowKeys): static
    {
        return $this->prop('checkedRowKeys',$checkedRowKeys);
    }

    /**
     * 在进行树型数据选择的时候是否级联
     * @param string|bool $cascade
     * @return $this
     */
    public function cascade(string|bool $cascade = true): static
    {
        return $this->prop("cascade",$cascade);
    }

    /**
     * 树形数据下后代节点在数据中的 key
     * @param string $childrenKey
     * @return $this
     */
    public function childrenKey(string $childrenKey = 'children'): static
    {
        return $this->prop('childrenKey',$childrenKey);
    }

    /**
     * 默认选中的 key 值
     * @param string|array $defaultCheckedRowKeys (string[] | int[])
     * @return $this
     */
    public function defaultCheckedRowKeys(string|array $defaultCheckedRowKeys): static
    {
        return $this->prop('defaultCheckedRowKeys',$defaultCheckedRowKeys);
    }

    /**
     * 默认展开行的 key 值
     * @param string|array $defaultExpandedRowKeys (string[] | int[])
     * @return $this
     */
    public function defaultExpandedRowKeys(string|array $defaultExpandedRowKeys): static
    {
        return $this->prop('defaultExpandedRowKeys',$defaultExpandedRowKeys);
    }

    /**
     * 是否默认展开全部可展开的行，不可在异步展开行时使用
     * @param string|bool $defaultExpandAll
     * @return $this
     */
    public function defaultExpandAll(string|bool $defaultExpandAll = true): static
    {
        return $this->prop("defaultExpandAll",$defaultExpandAll);
    }

    /**
     * 展开行的 key 值
     * @param string|array $expandedRowKeys (string[] | int[])
     * @return $this
     */
    public function expandedRowKeys(string|array $expandedRowKeys): static
    {
        return $this->prop('expandedRowKeys',$expandedRowKeys);
    }

    /**
     * 使用树形数据时行内容的缩进距离
     * @param string|int $indent
     * @return $this
     */
    public function indent(string|int $indent = 16): static
    {
        return $this->prop('indent',$indent);
    }

    /**
     * 过滤操作后页面的状态
     * @param string $paginationBehaviorOnFilter 'first' 为回到首页，'current' 为停留在当前页
     * @return $this
     */
    public function paginationBehaviorOnFilter(string $paginationBehaviorOnFilter = 'current'): static
    {
        return $this->prop('paginationBehaviorOnFilter',$paginationBehaviorOnFilter);
    }

    /**
     * 是否让表格主体的高度自动适应整个表格区域的高度，打开这个选项会让 table-layout 始终为 'fixed'
     * @param string|bool $flexHeight
     * @return $this
     */
    public function flexHeight(string|bool $flexHeight = true): static
    {
        return $this->prop("flexHeight",$flexHeight);
    }

    /**
     * 当表格数据只有一页时是否显示分页面
     * @param string|bool $paginateSinglePage
     * @return $this
     */
    public function paginateSinglePage(string|bool $paginateSinglePage = true): static
    {
        return $this->prop("paginateSinglePage",$paginateSinglePage);
    }

    /**
     * 表格内容的最大高度，可以是 CSS 属性值
     * @param string|int $maxHeight
     * @return $this
     */
    public function maxHeight(string|int $maxHeight): static
    {
        return $this->prop('maxHeight',$maxHeight);
    }

    /**
     * 表格内容的最低高度，可以是 CSS 属性值
     * @param string|int $minHeight
     * @return $this
     */
    public function minHeight(string|int $minHeight): static
    {
        return $this->prop('minHeight',$minHeight);
    }

    /**
     * 是否不设定行的分割线，当参数为true时，则单元格没有下边线
     * @param string|bool $singleColumn
     * @return $this
     */
    public function singleColumn(string|bool $singleColumn = true): static
    {
        return $this->prop("singleColumn",$singleColumn);
    }

    /**
     * 是否不设定列的分割线，当参数值为 true 时，则单元格没有右边线
     * @param string|bool $singleLine
     * @return $this
     */
    public function singleLine(string|bool $singleLine = true): static
    {
        return $this->prop("singleLine",$singleLine);
    }

    /**
     * 是否使用斑马线条纹
     * @param string|bool $striped
     * @return $this
     */
    public function striped(string|bool $striped = true): static
    {
        return $this->prop("striped",$striped);
    }

    /**
     * 展开行是否不随表格横向滚动
     * @param string|bool $stickyExpandedRows
     * @return $this
     */
    public function stickyExpandedRows(string|bool $stickyExpandedRows = true): static
    {
        return $this->prop("stickyExpandedRows",$stickyExpandedRows);
    }


    /**
     * 是否开启虚拟滚动，应对大规模数据，开启前请设定好 max-height。当 virtual-scroll 为 true 时，rowSpan 将不生效
     * @param string|bool $virtualScroll
     * @return $this
     */
    public function virtualScroll(string|bool $virtualScroll = true): static
    {
        return $this->prop("virtualScroll",$virtualScroll);
    }

    /**
     * 总结栏的位置
     * @param string $summaryPlacement
     * @return $this
     */
    public function summaryPlacement(string $summaryPlacement = 'top' | 'bottom'): static
    {
        return $this->prop("summaryPlacement",$summaryPlacement);
    }

    /**
     * 表格的 table-layout 样式属性，在设定 ellipsis 或 max-height 的情况下固定为 'fixed'
     * @param string $tableLayout
     * @return $this
     */
    public function tableLayout(string $tableLayout = 'auto' | 'fixed'): static
    {
        return $this->prop("tableLayout",$tableLayout);
    }

    /**
     * 表格总结栏的数据
     * @param string $summary type DataTableCreateSummary = (pageData: RowData[]) =>
    | Array<{
        [columnKey: string]: {
        value?: VNodeChild
        colSpan?: number
        rowSpan?: number
        }
    }>
    | {
        [columnKey: string]: {
        value?: VNodeChild
        colSpan?: number
        rowSpan?: number
        }
    }
     *
     * @return $this
     */
    public function summary(string $summary): static
    {
        return $this->prop('summary',$summary);
    }



    /**
     * 设置表格绑定key字段
     * @param string $selectKey
     * @return $this
     */
    public function selectKey(string $selectKey): static
    {
        return $this->prop('selectKey',$selectKey);
    }


    /**
     * 自定义单元格渲染，优先级低于列column 的 render
     * @param string $renderCell (value: any, rowData: object, column: DataTableBaseColumn) => VNodeChild
     * @return $this
     */
    public function renderCell(string $renderCell): static
    {
        return $this->events("renderCell",$renderCell);
    }

    /**
     * 自定义渲染展开图标
     * @param string $renderExpandIcon () => VNodeChild
     * @return $this
     */
    public function renderExpandIcon(string $renderExpandIcon): static
    {
        return $this->events("renderExpandIcon",$renderExpandIcon);
    }

    /**
     * 每一行上的类名
     * @param string $rowClassName string | (rowData: object, index : number) => string
     * @param bool $isSingle 是否返回简单类名
     * @return $this
     */
    public function rowClassName(string $rowClassName, bool $isSingle = true): static
    {
        if ($isSingle){
            return $this->prop("rowClassName", $rowClassName);
        }else{
            return $this->events("rowClassName",$rowClassName);
        }
    }


    /**
     * 通过行数据创建行的 key（如果你不想给每一行加上 key）
     * @param string $rowKey (rowData: object) => (number | string)
     * @return $this
     */
    public function rowKey(string $rowKey): static
    {
        return $this->events("rowKey",$rowKey);
    }

    /**
     * 自定义行属性
     * @param string $rowProps (rowData: object, rowIndex : number) => object
     * @return $this
     */
    public function rowProps(string $rowProps): static
    {
        return $this->events("rowProps",$rowProps);
    }

    /**
     * 异步展开树形数据的回调
     * @param string $onLoad (rowData: object) => Promise<void>
     * @return $this
     */
    public function onLoad(string $onLoad): static
    {
        return $this->events("onLoad",$onLoad);
    }

    /**
     * 表格主体滚动的回调
     * @param string $onScroll (e: Event) => void
     * @return $this
     */
    public function onScroll(string $onScroll): static
    {
        return $this->events("onScroll",$onScroll);
    }

    /**
     * checked-row-keys 值改变时触发的回调函数
     * @param string $event (keys: Array<string | number>, rows: object[], meta: { row: object | undefined, action: 'check' | 'uncheck' | 'checkAll' | 'uncheckAll' }) => void
     * @return $this
     */
    public function onUpdateCheckedRowKeys(string $event): static
    {
        return $this->events("onUpdate:checkedRowKeys",$event);
    }

    /**
     * expanded-row-keys 值改变时触发的回调函数
     * @param string $event (keys: Array<string | number>) => void
     * @return $this
     */
    public function onUpdateExpandedRowKeys(string $event): static
    {
        return $this->events("onUpdate:expandedRowKeys",$event);
    }

    /**
     * filters 数据改变时触发的回调函数
     * @param string $event (keys: Array<string | number>) => void
     * @return $this
     */
    public function onUpdateFilters(string $event): static
    {
        return $this->events("onUpdate:filters",$event);
    }

    /**
     * page 改变时触发的回调函数
     * @param string $event (page: number)
     * @return $this
     */
    public function onUpdatePage(string $event): static
    {
        return $this->events("onUpdate:page",$event);
    }

    /**
     * page-size 改变时触发的回调函数
     * @param string $event (pageSize: number) => void
     * @return $this
     */
    public function onUpdatePageSize(string $event): static
    {
        return $this->events("onUpdate:pageSize",$event);
    }

    /**
     * 如果变动列为多列排序则返回 DataTableSortState[] | null 否则返回 DataTableSortState | null
     * @param string $event (options: DataTableSortState | DataTableSortState[] | null) => void
     * @return $this
     */
    public function onUpdateSorter(string $event): static
    {
        return $this->events("onUpdate:sorter",$event);
    }


    /**
     * 表格内容的横向宽度，如果列被水平固定了，则需要设定它
     * @param int|string $scrollX
     * @return $this
     */
    public function scrollX(int|string $scrollX): static
    {
        $this->prop("scrollX",$scrollX);
        return $this;
    }

    /**
     * 属性参考 Scrollbar props
     * @param string|array $scrollbarProps
     * @return $this
     */
    public function scrollbarProps(string|array $scrollbarProps): static
    {
        $this->prop("scrollbarProps",$scrollbarProps);
        return $this;
    }

    /**
     * 表格 spin 的属性
     * @param string|array $spinProps { strokeWidth?: number, stroke?: string }
     * @return $this
     */
    public function spinProps(string|array $spinProps): static
    {
        $this->prop("spinProps",$spinProps);
        return $this;
    }

    /**
     * 设置搜索表单数据
     * @param array|string $searchModel
     * @return $this
     */
    public function searchModel(array|string $searchModel): static
    {
        $this->prop("searchModel",$searchModel);
        return $this;
    }

    /**
     * 设置搜索表单配置
     * @param array|string $searchForm
     * @return $this
     */
    public function searchForm(array|string $searchForm): static
    {
        $this->prop("searchForm",$searchForm);
        return $this;
    }

    /**
     * 设置行禁用选择
     * @param string $rowDisabled (rowData: object, rowIndex: number)=> boolean
     * @return $this
     */
    public function rowDisabled(string $rowDisabled): static
    {
        return $this->events("rowDisabled",$rowDisabled);
    }

    /**
     * 表格的左侧工具栏
     * @param mixed $leftToolbar
     * @param array $params
     * @return $this
     */
    public function slotLeftToolbar(mixed $leftToolbar, array $params = []): static
    {
        return $this->slot('leftToolbar',$leftToolbar, $params);
    }

    /**
     * 表格的右侧工具栏
     * @param mixed $rightToolbar
     * @param array $params
     * @return $this
     */
    public function slotRightToolbar(mixed $rightToolbar, array $params = []): static
    {
        return $this->slot('rightToolbar',$rightToolbar, $params);
    }

    /**
     * 表格的搜索内容
     * @param mixed $search
     * @param array $params
     * @return $this
     */
    public function slotSearch(mixed $search, array $params = []): static
    {
        return $this->slot('search',$search, $params);
    }

}
